package com.howard.webapp.familymanagement.controller;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.howard.webapp.familymanagement.service.BaseService;
import com.howard.webapp.familymanagement.util.Constant;

@Controller
public abstract class BaseController<T, ID extends Serializable> {
	protected Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
	protected abstract BaseService<T, ID> getService();
	
	@RequestMapping("/list")
	@ResponseBody
	public String list(
			@RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer rows,
            @RequestParam(required = false) String sort,
            @RequestParam(required = false) String order,
            Model model){
		System.out.println("BaseController.list, page="+page+",rows="+rows+",sort="+sort+",order="+order);
		int pageNum = page==null?1:page-1;
		int rowNum = rows==null?Constant.PAGE_SIZE:rows;
		String sortStr = sort==null?Constant.ID:sort;
		Direction orderDirect = "DESC".equalsIgnoreCase(order)?Direction.DESC:Direction.ASC;
		
		PageRequest request =
	            new PageRequest(pageNum, rowNum, orderDirect, sortStr);
		System.out.println("request="+gson.toJson(request));
		Page<T> pageResult = getService().getRepository().findAll(request);
		model.addAttribute("rows", pageResult.getContent());
		model.addAttribute("total", pageResult.getTotalElements());
		return gson.toJson(model);
	}
	
	@RequestMapping(value="/upd")
	@ResponseBody
	public Map<String, String> upd(@RequestBody T uiRecord)
	{
		Map<String, String> map = new HashMap<String, String>(1);
		System.out.println("BaseController.upd,record："+uiRecord+",data="+gson.toJson(uiRecord));
		T dbRecord = null;
		try{
			Object idObj = PropertyUtils.getProperty(uiRecord, Constant.ID); 
			if(idObj != null){
				Long id = Long.parseLong(BeanUtils.getProperty(uiRecord, Constant.ID));
				dbRecord = getService().getRepository().findOne(id);
				System.out.println("before dbRecord："+dbRecord+",dbRecorddata="+gson.toJson(dbRecord));
				Field[] fields = dbRecord.getClass().getDeclaredFields();
				for(Field field: fields ){
					String fieldName = field.getName();
					Object uiValue = PropertyUtils.getProperty(uiRecord, fieldName);
	//				System.out.println("fieldName="+fieldName+",uiValue="+uiValue);
					if(uiValue != null){
						PropertyUtils.setProperty(dbRecord, fieldName, uiValue);
					}
				}
			}
			else{
				dbRecord = uiRecord;
			}
			System.out.println("after dbRecord："+dbRecord+",dbRecorddata="+gson.toJson(dbRecord));
			
			getService().getRepository().save(dbRecord);
			System.out.println("save ok!!!");
			map.put("success", "true");
		}catch(Exception e){
			e.printStackTrace();
			map.put("success", "false");
			map.put("msg", e.getMessage());
		}
	    return map;
	}
	
	@RequestMapping("/del")
	@ResponseBody
	public String del(String[] ids, Model model){
		System.out.println("BaseController.del："+gson.toJson(ids));
		if(ids == null || ids.length < 1){
			model.addAttribute("success", false);
			model.addAttribute("msg", "请选择要删除记录！");
			return gson.toJson(model);
		}
		
		for(String id: ids){
			try{
				getService().getRepository().delete(Long.parseLong(id));
				model.addAttribute("success", true);
			}catch(Exception e){
				model.addAttribute("success", false);
				model.addAttribute("msg", e.getMessage());
			}
		}
		return gson.toJson(model);
	}
}
